home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 160_01 / bj < prev    next >
Text File  |  1985-11-24  |  15KB  |  695 lines

  1. ###makefile.
  2. FILES=bj.c error.c dekmgr.c \
  3.     getbet.c hndmgr.c nfrom.c outcom.c query.c takes.c
  4.  
  5. OBJECTS=bj.o error.o dekmgr.o \
  6.     getbet.o hndmgr.o nfrom.o outcom.o query.o takes.o
  7.  
  8. DEFS=local.h bj.h dekmgr.h hndmgr.h ttymgr.h
  9.  
  10. LINT=lint -phbxac
  11.  
  12. cleanup:
  13.     -rm *.o
  14.     -du
  15.  
  16. install:
  17.     size bj /a1/phi/bin/bj
  18.     cp bj /a1/phi/bin/bj; rm bj
  19.  
  20. print: Makefile $(DEFS) $(FILES)
  21.     pr $?
  22.     date >print
  23.  
  24. bj: $(DEFS) $(OBJECTS)
  25.     cc -o bj $(OBJECTS)
  26.  
  27. bj.lint: $(DEFS)  $(FILES)
  28.     $(LINT) >bj.lint $(FILES)
  29.  
  30. outcom.x: $(DEFS) outcom.c error.o
  31.     cc -o outcom.x -DTRYMAIN outcom.c error.o
  32.  
  33. all:
  34.     make bj
  35.     make bj.lint
  36.     make install
  37. ###bj.c
  38. /* bj - blackjack
  39.  *        Permission is hereby granted to reproduce and use bj
  40.  */
  41. #include "local.h"
  42. #include "bj.h"
  43. #include "dekmgr.h"
  44. #include "hndmgr.h"
  45. #include "ttymgr.h"
  46. main()
  47.     {
  48.     CASH action;    /* how much money has crossed the table */
  49.     CASH bet;        /* amount of player's current bet per hand */
  50.     CASH result;    /* net result of this hand, plus or minus */
  51.     CASH standing;    /* how much has player won or lost */
  52.     bool canhit;    /* can player's hand take hit? */
  53.     bool isdbl;        /* did player take DBLDN? */
  54.     bool isinsur;    /* did player take insurance? */
  55.     short hand;        /* current hand number */
  56.     short reply;    /* player's reply to DBLDN, SPLIT */
  57.     short tophand;    /* how many hands is player playing, 1 or 2 */
  58.  
  59.     printf("Copyright (c) Plum Hall Inc, 1983\n");
  60.     /* permission to copy and modify is granted, provided that
  61.      * this printout and comment remain intact
  62.      */
  63.     printf("\nWelcome to the Blackjack table\n");
  64.     action = standing = 0;
  65.     opndek();
  66.     while ((bet = getbet()) != 0)
  67.         {
  68.         tophand = 1;
  69.         isinsur = isdbl = NO;
  70.         if (deklow())
  71.             shuffl();
  72.         deal();
  73.         if (val(DEALER, 0) == 11)
  74.             isinsur = takes("i");
  75.         reply = query();
  76.         if (reply == SPLIT)
  77.             tophand = split();
  78.         else if (reply == DBLDN)
  79.             {
  80.             hit(1);
  81.             printf("\n");
  82.             isdbl = YES;
  83.             bet *= 2;
  84.             }
  85.         for (hand = 1; hand <= tophand; ++hand)
  86.             {
  87.             if (tophand == 2)
  88.                 printf("Hand %d:\n", hand);
  89.             canhit = !isdbl;
  90.             canhit &= !isbj(1);
  91.             canhit &= (reply != SPLIT || val(1, 0) != 11);
  92.             while (canhit && takes("h"))
  93.                 {
  94.                 canhit = hit(hand);
  95.                 printf("\n");
  96.                 }
  97.             if (21 < score(hand))
  98.                 printf("Bust\n");
  99.             }
  100.         printf("Dealer has ");
  101.         show(DEALER, 0);
  102.         printf(" + ");
  103.         show(DEALER, 1);
  104.         if (!allbst())
  105.             while (score(DEALER) < 17)
  106.                 hit(DEALER);
  107.         printf(" = %d\n", score(DEALER));
  108.         result = outcom(bet, tophand, isinsur, isdbl);
  109.         action += ABS(result);
  110.         standing += result;
  111.         printf("action = ");
  112.         printf(CASHOUT, action);
  113.         printf(" standing = ");
  114.         printf(CASHOUT, standing);
  115.         printf("\n");
  116.         }
  117.     printf("\nThanks for the game.\n");
  118.     exit(SUCCEED);
  119.     }
  120. ###bj.h
  121. /* bj.h - include-file for blackjack
  122.  */
  123.  
  124. /* defined types
  125.  */
  126. #define CASH long    /* dollars */
  127.  
  128. /* defined constants
  129.  */
  130. #define DEALER 0        /* which hand is dealer; not modifiable */
  131. #define NONE 0            /* no reply */
  132. #define DBLDN 1            /* reply: double down */
  133. #define SPLIT 2            /* reply: split pair */
  134. #define INSUR 3            /* takes: insurance */
  135. #define HIT   4            /* takes: hit */
  136. #define CASHIN "%ld"    /* input format for CASH data */
  137. #define CASHOUT "%ld"    /* output format for CASH data */
  138. ###dekmgr.c
  139. /* dekmgr - deck manager
  140.  */
  141. #include "local.h"
  142. #include "bj.h"
  143. #include "dekmgr.h"
  144. #define NCARDS 4 * 52
  145. static short deck[NCARDS] = 0;    /* the deck */
  146. static short nc = 0;            /* subscript of next card */
  147. static short shufpt = 0;        /* subscript of shuffle point */
  148. /* deklow - is deck at or past shuffle point?
  149.  */
  150. bool deklow()
  151.     {
  152.     return (shufpt <= nc);
  153.     }
  154. /* opndek - initialize the deck
  155.  */
  156. void opndek()
  157.     {
  158.     short i;
  159.     short low;
  160.     short varnum();
  161.  
  162.     for (low = 0; low < NCARDS; low += 52)
  163.         for (i = 0; i < 52; ++i)
  164.             deck[i + low] = i;
  165.     srand(varnum());
  166.     shuffl();
  167.     }
  168. /* shuffl - shuffle the deck
  169.  */
  170. void shuffl()
  171.     {
  172.     short t;        /* temporary for swap */
  173.     short i;        /* index for loop over cards */
  174.     short j;        /* index for swap */
  175.     short nfrom();    /* fn to produce random number */
  176.  
  177.     for (i = 0; i < NCARDS - 1; ++i)
  178.         {
  179.         j = nfrom(i, NCARDS - 1);
  180.         t = deck[j], deck[j] = deck[i], deck[i] = t;
  181.         }
  182.     shufpt = nfrom(NCARDS - 52, NCARDS - 36);
  183.     nc = 0;
  184.     printf("Shuffle\n");
  185.     }
  186.  
  187.  
  188.  
  189. /* tkcard - take a card
  190.  */
  191. short tkcard()
  192.     {
  193.     if (NCARDS <= nc)
  194.         shuffl();
  195.     return (deck[nc++]);
  196.     }
  197. /* varnum - return a varying startoff number
  198.  */
  199. short varnum()
  200.     {
  201.     long time();    /* SYSTEM DEPENDENT - NEEDS CLOCK */
  202.  
  203.     return ((short)time(0));
  204.     }
  205. ###dekmgr.h
  206. /* dekmgr.h - interface for deck manager
  207.  */
  208. bool deklow();
  209. void opndek();
  210. void shuffl();
  211. short tkcard();
  212. ###error.c
  213. /* error - print fatal error message
  214.  */
  215. #include "local.h"
  216. void error(s1, s2)
  217.     char s1[], s2[];
  218.     {
  219.     write(STDERR, s1, strlen(s1));
  220.     write(STDERR, " ", 1);
  221.     write(STDERR, s2, strlen(s2));
  222.     write(STDERR, "\n", 1);
  223.     exit(FAIL);
  224.     }
  225. ###getbet.c
  226. /* getbet - get the player's bet
  227.  */
  228. #include "local.h"
  229. #include "bj.h"
  230. #define MINBET 2
  231. #define MAXBET 1000
  232. CASH getbet()
  233.     {
  234.     char line[BUFSIZ];    /* input line */
  235.     short retn;            /* return from getln and sscanf */
  236.     CASH bet;            /* player's bet */
  237.  
  238.     printf("\n\nYour bet (amount): ");
  239.     FOREVER
  240.         {
  241.         retn = getln(line, BUFSIZ);
  242.         if (retn == EOF)
  243.             return (0);
  244.         retn = sscanf(line, CASHIN, &bet);
  245.         if (retn != 1 || bet < MINBET || MAXBET < bet)
  246.             printf("Number from %d to %d please: ",
  247.                 MINBET, MAXBET);
  248.         else
  249.             return (bet);
  250.         }
  251.     }
  252. ###hndmgr.c
  253. /* hndmgr - hand manager
  254.  */
  255. #include "local.h"
  256. #include "bj.h"
  257. #include "hndmgr.h"
  258. #include "dekmgr.h"
  259. static char spots[13][3] = 
  260.     {"A", "2", "3", "4", "5", "6", "7", "8", "9",
  261.     "10", "J", "Q", "K"};
  262. static char suits[4][2] = {"S", "H", "D", "C"};
  263. static short hands[3][12] = 0;    /* three hands */
  264. static short ncards[3] = 0;        /* how many cards in each hand */
  265. static short tophand = 0;        /* how many player hands active */
  266. /* allbst - are all player's hands busted?
  267.  */
  268. bool allbst()
  269.     {
  270.     if (score(1) <= 21 || (tophand == 2 && score(2) <= 21))
  271.         return (NO);
  272.     else
  273.         return (YES);
  274.     }
  275. /* deal - initialize the hands
  276.  */
  277. void deal()
  278.     {
  279.     hands[1][0] = tkcard();
  280.     hands[DEALER][0] = tkcard();
  281.     hands[1][1] = tkcard();
  282.     hands[DEALER][1] =tkcard();
  283.     ncards[DEALER] = ncards[1] = 2;
  284.     tophand = 1;
  285.     printf("The dealer shows ");
  286.     show(DEALER, 0);
  287.     printf("\nYou have ");
  288.     show(1, 0);
  289.     printf(" + ");
  290.     show(1, 1);
  291.     printf("\n");
  292.     }
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303. /* hit - add a card to a hand
  304.  */
  305. bool hit(h)
  306.     short h;        /* which hand */
  307.     {
  308.     hands[h][ncards[h]] = tkcard();
  309.     printf(" + ");
  310.     show(h, ncards[h]);
  311.     ++ncards[h];
  312.     if (21 < score(h) || h == DEALER && 17 <= score(h))
  313.         return (NO);
  314.     else
  315.         return (YES);
  316.     }
  317. /* isbj - is hand a "natural" 2-card blackjack?
  318.  */
  319. bool isbj(h)
  320.     short h;        /* which hand */
  321.     {
  322.     if (h == DEALER)
  323.         return (ncards[DEALER] == 2 && score(DEALER) == 21);
  324.     else if (h == 1)
  325.         return (tophand == 1 && ncards[1] == 2 && score(1) == 21);
  326.     else
  327.         return (NO);
  328.     }
  329. /* score - tell blackjack value of hand
  330.  */
  331. short score(h)
  332.     short h;        /* which hand */
  333.     {
  334.     short aces = 0;    /* number of aces in hand */
  335.     short i;        /* card counter */
  336.     short sum = 0;    /* accumulated value of hand */
  337.  
  338.     for (i = 0; i < ncards[h]; ++i)
  339.         {
  340.         sum += val(h, i);
  341.         if (val(h, i) == 11)
  342.             ++aces;
  343.         }
  344.     for (i = aces; 0 < i; --i)
  345.         if (21 < sum)
  346.             sum -= 10;
  347.     return (sum);
  348.     }
  349.  
  350.  
  351.  
  352.  
  353. /* show - print a card
  354.  */
  355. void show(h, i)
  356.     short h;    /* which hand */
  357.     short i;    /* which card */
  358.     {
  359.     printf("%s", spots[hands[h][i] % 13]);
  360.     printf("%s", suits[hands[h][i] / 13]);
  361.     }
  362. /* split - split the players pair if allowed
  363.  */
  364. short split()
  365.     {
  366.     if (val(1, 0) != val(1, 1))
  367.         return (1);
  368.     hands[2][0] = hands[1][1];
  369.     hands[1][1] = tkcard();
  370.     hands[2][1] = tkcard();
  371.     ncards[2] = 2;
  372.     printf("Hand 1: "); show(1, 0); printf(" + "); show(1, 1);
  373.     printf("\n");
  374.     printf("Hand 2: "); show(2, 0); printf(" + "); show(2, 1);
  375.     printf("\n");
  376.     tophand = 2;
  377.     return (2);
  378.     }
  379. /* val - tell value of card n of hand h
  380.  */
  381. short val(h, i)
  382.     short